﻿/*
Copyright (c) 2010 Vratislav Cermak (vratacermak@gmail.com)
 
This file is part of TeachMe Project. See http://code.google.com/p/teach-me for more information.
 
TeachMe is an open source project. Using of TeachMe is free of charge.
It is distributed under GNU General Public License version 3 (GPLv3).
GPLv3 can be found at http://www.gnu.org/licenses/gpl.html.
 
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

using System;
using System.IO;
using System.Net;
using System.Threading;
using TeachMe.Application.Forms;
using TeachMe.Application.Properties;

namespace TeachMe.Application
{
    public class OnlineVersionChecker
    {
        private class VersionCheckerThreadWorkerData
        {
            public IVersionDataReceiver Receiver { get; set; } 
            public string CurrentVersion { get; set; }
            public string Id { get; set; }
            public string Language { get; set; }
        }        

        public enum Result
        {
            Failed,
            New,
            UpToDate
        }

        public interface IVersionDataReceiver
        {
            void Process(Result result, OnlineVersion onlineVersion = null);
        }

        private static void ThreadWorker(object obj)
        {
            VersionCheckerThreadWorkerData worker = obj as VersionCheckerThreadWorkerData;
            if (worker == null)
            {
                throw new InvalidOperationException();
            }

            OnlineVersion onlineVersion = null;

            using (WebClient client = new WebClient())
            {
                // here we are downloading php page with online version info
                // as user agent we put product version, os version (and platform) and app language

                string userAgent = String.Format("TeachMe/{0} ({1}; {2}; {3})", worker.CurrentVersion, Environment.OSVersion.VersionString, Environment.OSVersion.Platform, worker.Language);
                string link = "http://www.teachme.cz/version.php";

                client.Headers.Add("user-agent", userAgent);

                try
                {
                    Logging.Debug(typeof(OnlineVersion), "Checking new version with: {0}", link);

                    // TODO: timeout

                    using (Stream data = client.OpenRead(link))
                    {
                        using (StreamReader reader = new StreamReader(data))
                        {
                            onlineVersion = Utilities.Deserialize<OnlineVersion>(reader.ReadToEnd());
                        }
                    }
                }
                catch (WebException e)
                {
                    Logging.Error(typeof(OnlineVersion), e, "Could check new version availability.");
                }
            }

            if (onlineVersion != null)
            {
                if (Utilities.CompareVersions(worker.CurrentVersion, onlineVersion.Value) < 0)
                {
                    worker.Receiver.Process(Result.New, onlineVersion);
                }
                else
                {
                    worker.Receiver.Process(Result.UpToDate);
                }
            }
            else
            {
                worker.Receiver.Process(Result.Failed);
            }
        }

        public static void Check(IVersionDataReceiver receiver, string currentVersion, string id, string language)
        {
            VersionCheckerThreadWorkerData worker = new VersionCheckerThreadWorkerData { Receiver = receiver, CurrentVersion = currentVersion, Id = id, Language = language };
            Thread thread = new Thread(ThreadWorker) { CurrentUICulture = Thread.CurrentThread.CurrentUICulture };
            thread.Start(worker);
        }
    }
}
